Elastic Load Balancingで複数のゾーンにわたって振り分けるときに気をつけること
大量のトラフィックが予想されるサービスを構築する際にAWSを使うと Elastic Load Balancing と Auto Scaling を組み合わせて負荷状況に応じて EC2 を自動でスケールさせることができます。普段はまあまあだけど急に跳ね上がる可能性もある場合にはとても便利な仕組みですよね。
今回はさらに複数の Availability Zone(Multi-AZ)にわたってEC2を配置する際に気をつけたほうがいいところを紹介させていただきたいと思います。
Elastic Load Balancingって?
Elastic Load Balancing(以下ELB)は配下にある複数のEC2の負荷状況に応じてトラフィックを分散してくれます。さらに Health Check という仕組みを使うことでアプリケーションの不具合を検知することもできます。
各設定や状況はAWS Consoleから確認できるのでとても使いやすいツールだと思います。
Auto Scalingって?
Auto Scaling(以下AS)は設定したルールでEC2インスタンスを増やしたり(スケールアウト)減らしたり(スケールイン)できます。ルールというのは例えばELB配下のEC2のグループ全体で ”平均のCPU使用率がしきい値を超えた場合にインスタンスを増やす” とか ”夜中の1時になったらインスタンスを減らす” とかが可能になります。
ASはAWS Consoleが提供されていないのでコマンドラインツールを使用しなければいけません。便利な機能なのにちょっとだけ残念ですね。
Availability Zoneって?
Availability Zone(以下AZ)は一つのリージョン(東京リージョンなど)の中でさらに物理的に分けられた環境のことです。災害時にもそれぞれが影響を受けにくいように設計されているようです。リージョンとはちがいゾーンごとに料金が変わることはありません。
EC2インスタンスを複数のAZに配置することで耐障害性を高めることができます。
Multi-AZにEC2を配置する
AWS Consoleから操作できます。EC2ページの左側のメニューから NETWORK & SECURITY > Load Balancers へと辿った画面でELBの作成、削除、編集が行えます。
ELBのリストから設定変更したいものを選択して、リスト下部に表示される詳細エリアの Instances タブを選択します。するとInstancesとAvailability Zonesの2つのテーブルが表示されます。
両者とも右上の赤丸で囲った +/- のボタンから追加と削除が行えます。デフォルトでは使用しているリージョンのAZの全てがAvailability Zonesのテーブルに入っていると思いますのでaとcに一つずつEC2を配置すると上記のようになります。
各ゾーンのインスタンス数が大事
さてやっとここから本題です。Multi-AZにインスタンスを配置したらゾーン毎の数を揃えておくことがとても大事です。ELBの振り分けロジックは公開されていませんが、おそらく各AZに対してはラウンドロビン的に振り分けが行われ、AZ内ではインスタンスの負荷状況を確認しつつ偏りがないように振り分けが行われているようです。
ですのでゾーンAに1つ、ゾーンCに2つのインスタンスが配置されている場合、各AZにトラフィックが均等に振り分けられるのでゾーンAにいるインスタンスはゾーンCにいる一つのインスタンスよりも倍の仕事をこなさなければいけなくってしまいます!
これではCPU使用率の平均をとってASを設定している場合に不都合な状況となってしまします。
例えば以下のようにゾーンCの各インスタンスのCPU使用率が30%ずつだと、ゾーンAは1つしかいないので倍の60%くらいになるはずです。
この場合にASのスケールアウトのしきい値を50%に設定してあると、(60 + 30 + 30) ÷ 3 = 40 となってしまい1つだけ負荷が高いままスケールアウトしなくなってしまいます!誰かこの問題に名前をつけてください。
おまけ
0個インスタンスのAZはリストから消しておいたほうがいいです
インスタンスが1つも含まれていないAZをELBのリストに入れておくとトラフィックを受けることが出来ないAZに振り分けてしまうことがあるのでリクエストタイムアウトが頻繁に起きます。アプリケーション自体に問題ないのに何事だ!と思ったらこれが原因だったことがあるので気をつけましょう。
まとめ
ELBを使う上で割りと基本的な部分かなと思えるところなんですが情報が少ないと思ったので書いてみました。ELBは便利ですが内部仕様が公開されていないので予期しない事態が起きるとデバッグがしづらいですが動作がわかってしまえば単純ですね!